package com.baosight.risk.web.freemarker;

import java.io.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baosight.risk.api.riaa.RiaaQuesInquiryService;
import com.baosight.risk.api.ridc.RidcRiskService;
import com.baosight.risk.api.rifi.RifiRiskFinishService;
import com.baosight.risk.api.riim.RiimRiskImportService;
import com.baosight.risk.api.rire.RireReportWordService;
import com.baosight.risk.api.rire.RireRiskReportService;
import com.baosight.risk.api.xtdc.XtdcAttachService;
import com.baosight.risk.base.controller.BaseController;
import com.baosight.risk.common.bean.BeanUtils;
import com.baosight.risk.common.file.FileManager;
import com.baosight.risk.common.freemarker.ResumeWord;
import com.baosight.risk.common.pdf.dto.Office2PdfDto;
import com.baosight.risk.common.pdf.service.Office2PdfService;
import com.baosight.risk.common.result.AjaxResult;
import com.baosight.risk.common.utils.ShiroUtils;
import com.baosight.risk.common.utils.StringUtils;
import com.baosight.risk.service.rire.entity.RireRiskWarningStatus;
import com.baosight.risk.service.xtdc.entity.XtdcAttach;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Api(value = "导出word", description = "word编辑器", produces = MediaType.APPLICATION_JSON)
@RestController
@Slf4j
@RequestMapping("freemarker")
public class FreeMarkerController extends BaseController {
    @Autowired
    private RiimRiskImportService importService;

    @Autowired
    private Office2PdfService office2PdfService;

    @Autowired
    private FileManager fileManager;

    @Autowired
    private RifiRiskFinishService riskFinishService;

    @Autowired
    private RireReportWordService reportWordService;

    @Autowired
    private RidcRiskService ridcRiskService;

    @Autowired
    private XtdcAttachService xtdcAttachService;

    @Autowired
    private RiaaQuesInquiryService riaaQuesImquiryService;

    @Autowired
    private RireRiskReportService rireRiskReportService;

    /**
     * 导出word
     *
     * @param response
     * @param map      参数
     * @param model    word模版名称
     * @param wordName 生成word文件名称
     * @param fileName 生成word在服务器上的文件名称
     * @throws IOException
     */
    public void exportWord(HttpServletResponse response, Map map, String model, String wordName, String fileName) throws Exception {
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        InputStream inputStream = null;
        try {
            //调用工具类WordGenerator的createDoc方法生成Word文档
            file = ResumeWord.createDoc(map, model, wordName);
            fin = new FileInputStream(file);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.addHeader("Content-Disposition", "attachment;filename=" + file.getName());
            out = response.getOutputStream();
            //返回到浏览器
            inputStream = new FileInputStream(file);
            //上传服务器
            FileManager.Config config = fileManager.getConfig();
            config.setBusinessCode(fileName);
            config.setFilename(file.getName());
            config.setInputStream(fin);
            fileManager.saveFile(config);

            byte[] buffer = new byte[1024];//缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }

        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            if (fin != null){ fin.close();}
            if (out != null){ out.close();}
            if (inputStream != null){ inputStream.close();}
            if (file != null){ file.delete();} // 删除临时文件
        }

    }

    /**
     * 在线生成word，再转换成pdf
     *
     * @param map       freemarker导出参数
     * @param model     word模版名称
     * @param wordName      生成word文件名称
     */
    public void exportPDF(Map map, String model, String wordName, String sourceGuid, String sourceModel, boolean replace){
        File file = null;
        try {
            //调用工具类WordGenerator的createDoc方法生成Word文档
            file = ResumeWord.createDoc(map, model, wordName);
            //在服务器上生成目录
            FileManager.Config config = fileManager.getConfig();
            config.setBusinessCode(sourceModel);
            config.setFilename(file.getName());
            String dir = fileManager.generateDir(config);
            String pdfName = file.getName().substring(0, file.getName().indexOf(".")) + ".pdf";
            String pdfPath = dir + pdfName;

            log.info("生成WORDStart----");
            //上传word文件
            FileOutputStream os = null;
            // 新建一个空白pdf文档
            os = new FileOutputStream(dir + file.getName().substring(0, file.getName().indexOf("."))+".docx");
            // Address是将要被转化的word文档
            Document doc = new Document(new FileInputStream(file));
            doc.save(os, SaveFormat.WORD_ML);
            log.info("生成WORDEnd----");

            log.info("生成PDFStart----");
            //把word转换成pdf
            AsposeWordToPDF.docToPdfWatermark(file, pdfPath);
            os.close();
            log.info("生成PDFEnd----");


            File pdf = new File(pdfPath);
            if (pdf != null && pdf.exists()){
                if (replace) {
                    xtdcAttachService.deleteFilesBySourceAndModel(sourceGuid, sourceModel);
                }
                String fileType = fileManager.getFileType(pdfName);

                //存入数据库
                XtdcAttach attach = (XtdcAttach) BeanUtils.initBean(new XtdcAttach());
                attach.setFileName(pdfName);
                attach.setFilePath(pdfPath);
                attach.setFileSize(pdf.length());
                attach.setFileType(fileType);
                attach.setExt5(ShiroUtils.getUser().getUserDesc());
                attach.setSourceGuid(sourceGuid);
                attach.setSourceModel(sourceModel);
                attach.setFolderId("1");
                xtdcAttachService.insert(attach);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("生成pdf异常："+e.getMessage());
        } finally {
            if (file != null){ file.delete(); } // 删除临时文件
        }
    }

    /**
     * 在线生成pdf返回到用户浏览器
     *
     * @param response http响应
     * @param map       freemarker导出参数
     * @param model     word模版名称
     * @param wordName      生成word文件名称
     * @param dirName       生成word在服务器上的目录名称
     */
    public void exportPDF(HttpServletResponse response, Map map, String model, String wordName, String dirName){
        File file = null;
        File pdf = null;
        ServletOutputStream out = null;
        InputStream inputStream = null;
        try {
            //调用工具类WordGenerator的createDoc方法生成Word文档
            file = ResumeWord.createDoc(map, model, wordName);
            //在服务器上生成目录
            FileManager.Config config = fileManager.getConfig();
            config.setBusinessCode(dirName);
            config.setFilename(file.getName());
            String dir = fileManager.generateDir(config);
            String pdfPath = dir + file.getName().substring(0, file.getName().indexOf(".")) + ".pdf";
            //把word转换成pdf
            AsposeWordToPDF.docToPdfWatermark(file, pdfPath);

            pdf = new File(pdfPath);
            if(pdf != null && pdf.exists()){
                //设置响应参数
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/msword");
                response.addHeader("Content-Disposition", "attachment;filename=" + file.getName());
                out = response.getOutputStream();
                //pdf返回到浏览器
                inputStream = new FileInputStream(pdf);
                byte[] buffer = new byte[1024];//缓冲区
                int bytesToRead = -1;
                // 通过循环将读入的Word文件的内容输出到浏览器中
                while ((bytesToRead = inputStream.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            try {
                if (out != null){ out.close();}
                if (inputStream != null){ inputStream.close();}
                // 删除临时文件
                if (file != null){ file.delete(); }
                if (pdf != null){ pdf.delete(); }
            }catch (Exception e){
                log.error(e.getMessage());
            }

        }
    }

    /**
     * 预览PDF
     *
     * @param map      参数
     * @param model    word模版名称
     * @param wordName 生成word文件名称
     * @throws IOException
     */
    public Office2PdfDto previewPDF(Map map, String model, String wordName) {
        //调用工具类WordGenerator的createDoc方法生成Word文档
        File file = ResumeWord.createDoc(map, model, wordName);
        Office2PdfDto pdfDto = office2PdfService.office2Pdf(file);
        if (file != null) file.delete(); // 删除临时文件
        return pdfDto;
    }

    @GetMapping("exportWordByImport")
    @ApiOperation("导出重点风险实施方案word")
    public AjaxResult exportWordByImport(HttpServletRequest request, HttpServletResponse response, @RequestParam("importId") String importId) throws Exception {
        Map map = importService.importWord(importId);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "import.ftl", "zhongdianfengxian", "zhongdianfengxianWORD");
        return success();
    }

    @PostMapping("exportWordByMainImport")
    @ApiOperation("导出汇总重点风险实施方案word")
    public AjaxResult exportWordByMainImport(HttpServletRequest request, HttpServletResponse response, @RequestBody(required = false) List<String> importIds) throws Exception {
        Map map = importService.mainImportWord(importIds);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "mainImport.ftl", "zhongdianfengxian", "zhongdianfengxianWORD");
        return success();
    }


    @GetMapping("previewPDFByImport")
    @ApiOperation("预览重点风险实施方案PDF")
    public AjaxResult previewPDFByImport(HttpServletRequest request, HttpServletResponse response, @RequestParam("importId") String importId) throws Exception {
        Map map = importService.importWord(importId);
        if (map.isEmpty()) {
            log.error("数据为空！");
            throw new Exception("数据为空");
        }
        Office2PdfDto office2PdfDto = previewPDF(map, "import.ftl", "zhongdianfengxianPDF");
        return success(office2PdfDto);
    }


    @PostMapping("exportWordByReport")
    @ApiOperation("导出重点风险披露报告word")
    public AjaxResult exportWordByReport(HttpServletRequest request, HttpServletResponse response, String importId) throws Exception {
        Map map = reportWordService.reportWord(importId, "2");
        if (map.isEmpty()) {
            log.error("数据为空！");
            throw new Exception("数据为空");
//            return error("数据为空！");
        }
        if(map.get("specialFlag")!=null && "Y".equals(map.get("specialFlag").toString()) ){
            exportWord(response, map, "specialReport.ftl", "pilubaogao", "pilubaogaoWORD");
        }else{
            exportWord(response, map, "report.ftl", "pilubaogao", "pilubaogaoWORD");
        }
        return success();
    }

    @GetMapping("previewPDFByFinish")
    @ApiOperation("预览重点风险结题PDF")
    public AjaxResult previewPDFByFinish(HttpServletRequest request, HttpServletResponse response, @RequestParam("importId") String importId) throws Exception {
        Map map = riskFinishService.importWord(importId);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        Office2PdfDto office2PdfDto = previewPDF(map, "finish.ftl", "fengxianjietiPDF");
        return success(office2PdfDto);
    }

    @GetMapping("exportWordByFinish")
    @ApiOperation("导出重点风险结题word")
    public AjaxResult exportWordByFinish(HttpServletRequest request, HttpServletResponse response, @RequestParam("importId") String importId) throws Exception {
        Map map = riskFinishService.importWord(importId);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "finish.ftl", "fengxianjieti", "fengxianjietiWORD");

        return success();
    }

    @PostMapping("exportWordByMainFinish")
    @ApiOperation("导出重点风险结题汇总word")
    public AjaxResult exportWordByMainFinish(HttpServletRequest request, HttpServletResponse response, @RequestBody List<String> importIds) throws Exception {
        Map map = riskFinishService.importWordList(importIds);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "mainFinish.ftl", "fengxianjieti", "fengxianjietiWORD");

        return success();
    }


    @GetMapping("exportWordByArchives")
    @ApiOperation("导出重点风险=风险档案word")
    public AjaxResult exportWordByArchives(HttpServletRequest request, HttpServletResponse response, @RequestParam("ridcId") String ridcId) throws Exception {
        Map map = ridcRiskService.importWord(ridcId);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "ridcRisk.ftl", "fengxiandangan", "fengxiandanganWORD");
        return success();
    }

    @GetMapping("exportWordsByArchives")
    @ApiOperation("导出重点风险=汇总风险档案word")
    public AjaxResult exportWordsByArchives(HttpServletRequest request, HttpServletResponse response, @RequestParam("ridcIds") String ridcIds) throws Exception {
        if (StringUtils.isEmpty(ridcIds)){
            log.error("ID数据为空！");
            throw new Exception("ID数据为空");
        }
         String pageSplit = "<w:p><w:pPr><w:keepNext w:val=\"off\"/><w:keepLines w:val=\"off\"/><w:pageBreakBefore w:val=\"off\"/><w:widowControl w:val=\"off\"/><w:tabs><w:tab w:val=\"center\" w:pos=\"4153\"/><w:tab w:val=\"right\" w:pos=\"8306\"/></w:tabs><w:kinsoku/><w:wordWrap/><w:overflowPunct/><w:topLinePunct w:val=\"off\"/><w:autoSpaceDE/><w:autoSpaceDN/><w:adjustRightInd/><w:snapToGrid w:val=\"off\"/><w:spacing w:before=\"156\" w:before-lines=\"50\" w:after=\"0\" w:after-lines=\"0\" w:line=\"240\" w:line-rule=\"at-least\"/><w:ind w:left=\"0\" w:left-chars=\"0\" w:right=\"0\" w:right-chars=\"0\" w:first-line=\"0\" w:first-line-chars=\"0\"/><w:jc w:val=\"both\"/><w:textAlignment w:val=\"auto\"/><w:outlineLvl w:val=\"9\"/><w:rPr><w:rFonts w:ascii=\"微软雅黑\" w:h-ansi=\"微软雅黑\" w:fareast=\"微软雅黑\" w:cs=\"微软雅黑\" w:hint=\"fareast\"/><w:b w:val=\"off\"/><w:color w:val=\"auto\"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii=\"微软雅黑\" w:h-ansi=\"微软雅黑\" w:fareast=\"微软雅黑\" w:cs=\"微软雅黑\" w:hint=\"default\"/><w:b w:val=\"off\"/><w:color w:val=\"auto\"/><w:lang w:fareast=\"ZH-CN\"/></w:rPr><w:br w:type=\"page\"/></w:r></w:p>";
        String[] idArray=ridcIds.split(",");
        List datas=new LinkedList();
        for (String id:idArray){
            Map map = ridcRiskService.importWord(id);
            if (map.isEmpty()) {
                log.error("数据为空！");
                throw new Exception("数据为空");
            }
            map.put("pageSplit", pageSplit);
            datas.add(map);
        }
        if (datas.isEmpty()){
            log.error("数据为空！");
            throw new Exception("数据为空");
        }

        Map dataMap=new HashMap();
        dataMap.put("datas",datas);
        exportWord(response, dataMap, "summaryRidcRisk.ftl", "huizongfengxiandangan", "huizongfengxiandanganWORD");
        return success();
    }



    @GetMapping("previewPDFByArchives")
    @ApiOperation("预览重点风险档案PDF")
    public AjaxResult previewPDFByArchives(HttpServletRequest request, HttpServletResponse response, @RequestParam("ridcId") String ridcId) throws Exception {
        Map map = ridcRiskService.importWord(ridcId);
        if (map.isEmpty()) {
            log.error("数据为空！");
            throw new Exception("数据为空");
//            return error("数据为空！");
        }
        Office2PdfDto office2PdfDto = previewPDF(map, "ridcRisk.ftl", "fengxiandanganPDF");
        return success(office2PdfDto);
    }

    @PostMapping("exportWordByMainReport")
    @ApiOperation("导出汇总披露报告word")
    public AjaxResult exportWordByMainReport(HttpServletRequest request, HttpServletResponse response,
                                             @RequestBody(required = false) List<String> reportIds, String acctYear, String quarter) throws Exception {
        //如果年度季度不为空的时候，根据年度和季度查询数据
        if (StringUtils.isNotEmpty(acctYear) && StringUtils.isNotEmpty(quarter)) {
            RireRiskWarningStatus warningStatus = new RireRiskWarningStatus();
            warningStatus.setAcctYear(acctYear);
            warningStatus.setQuarterCode(quarter);
            reportIds = rireRiskReportService.selectList(warningStatus).stream().map(RireRiskWarningStatus::getId).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(reportIds)) {
            log.error("数据为空！");
            throw new Exception("数据为空");
//            return error("数据为空！");
        }
        Map map = reportWordService.reportWordList(reportIds);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "mainReport.ftl", "mainReport", "mainReportWord");
        return success();
    }

    @PostMapping("exportWordByTopReport")
    @ApiOperation("导出Top3风险自评报告word")
    public AjaxResult exportWordByTopReport(HttpServletRequest request, HttpServletResponse response,
                                             @RequestBody(required = false) List<String> reportIds, String acctYear, String quarter) throws Exception {
        //如果年度季度不为空的时候，根据年度和季度查询数据
        if (StringUtils.isNotEmpty(acctYear) && StringUtils.isNotEmpty(quarter)) {
            RireRiskWarningStatus warningStatus = new RireRiskWarningStatus();
            warningStatus.setAcctYear(acctYear);
            warningStatus.setQuarterCode(quarter);
            reportIds = rireRiskReportService.selectList(warningStatus).stream().map(RireRiskWarningStatus::getId).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(reportIds)) {
            log.error("数据为空！");
            throw new Exception("数据为空");
//            return error("数据为空！");
        }
        //Map map = reportWordService.reportWordList(reportIds);
        Map map = reportWordService.reportTopWord(reportIds);
        if (map.isEmpty()) {
            log.error("数据为空！");
//            return error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "ririRisk.ftl", "ririRisk", "ririRisk");
        return success();
    }

    @GetMapping("previewPDFByMainReport")
    @ApiOperation("预览导出汇总披露报告PDF")
    public AjaxResult previewPDFByMainReport(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "importId", defaultValue = "", required = false) String importId) throws Exception {
        Map map = new HashMap();
        Office2PdfDto office2PdfDto = previewPDF(map, "mainReport.ftl", "123");
        return success(office2PdfDto);

    }

    @GetMapping("exportWordByQues")
    @ApiOperation("导出调研问卷word")
    public AjaxResult exportWordByQues(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") String id) throws Exception {
    	String manageCompCode = "";
    	if("BGTA".equals(ShiroUtils.getUser().getManageCompCode())){
    		manageCompCode = "BGTA";
    	}

    	Class claz = riaaQuesImquiryService.getClass();
    	Method m = claz.getDeclaredMethod("exportQues"+manageCompCode, String.class);
    	Map map = (Map)m.invoke(riaaQuesImquiryService, id);
        //Map map = riaaQuesImquiryService.exportQuesBGTA(id);
        if (map.isEmpty()) {
            log.error("数据为空！");
            throw new Exception("数据为空");
        }
        exportWord(response, map, "ques"+manageCompCode+".ftl", "diaoyanwenjuan", "diaoyanwenjuanWORD");
        return success();
    }


}
